package com.joolun.framework.socket;


import com.corundumstudio.socketio.AuthorizationListener;
import com.corundumstudio.socketio.HandshakeData;
import com.corundumstudio.socketio.SocketConfig;
import com.corundumstudio.socketio.SocketIOServer;
import com.joolun.common.utils.StringUtils;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;


/**
 * @SocketIOConfig socketIo配置类
 * @Author chenbinbin
 * @Version 1.0
 **/
@Configuration
public class SocketIOConfig implements InitializingBean {

    private static final Logger log = LoggerFactory.getLogger(SocketIOHandler.class);

    /**
     * socket监听器
     **/
    @Resource
    @Lazy
    private SocketIOHandler socketIOHandler;


    /**
     * socketIo ip地址
     **/
    @Value("${socketIo.host}")
    private String host;

    /**
     * socketIo 端口
     **/
    @Value("${socketIo.port}")
    private Integer port;

    /**
     * socket连接数大小（如只监听一个端口boss线程组为1即可）
     **/
    @Value("${socketIo.bossCount}")
    private int bossCount;

    /**
     * socket最大连接数
     **/
    @Value("${socketIo.workCount}")
    private int workCount;

    /**
     * 开启全部自定义事件响应
     **/
    @Value("${socketIo.allowCustomRequests}")
    private boolean allowCustomRequests;

    /**
     * 协议升级超时时间（毫秒），默认10秒。HTTP握手升级为ws协议超时时间
     **/
    @Value("${socketIo.upgradeTimeout}")
    private int upgradeTimeout;

    /**
     * Ping消息超时时间（毫秒），默认60秒，这个时间间隔内没有接收到心跳消息就会发送超时事件
     **/
    @Value("${socketIo.pingTimeout}")
    private int pingTimeout;


    /**
     * Ping消息间隔（毫秒），默认25秒。客户端向服务器发送一条心跳消息间隔
     **/
    @Value("${socketIo.pingInterval}")
    private int pingInterval;


    /**
     * 设置http交互最大内容长度
     **/
    @Value("${socketIo.maxHttpContentLength}")
    private int maxHttpContentLength;

    /**
     * Ping消息间隔（毫秒），默认25秒。客户端向服务器发送一条心跳消息间隔
     **/
    @Value("${socketIo.maxFramePayloadLength}")
    private int maxFramePayloadLength;


    @Override
    public void afterPropertiesSet() throws Exception {
        SocketConfig socketConfig = new SocketConfig();
        socketConfig.setReuseAddress(true);
        socketConfig.setTcpNoDelay(true);
        socketConfig.setSoLinger(0);

        com.corundumstudio.socketio.Configuration configuration = new com.corundumstudio.socketio.Configuration();
        configuration.setSocketConfig(socketConfig);
        // host在本地测试可以设置为localhost或者本机IP，在Linux服务器跑可换成服务器IP
       // configuration.setHostname(host);
        configuration.setPort(port);
        // socket连接数大小（如只监听一个端口boss线程组为1即可）
        configuration.setBossThreads(bossCount);
        configuration.setWorkerThreads(workCount);
        configuration.setAllowCustomRequests(allowCustomRequests);
        // 协议升级超时时间（毫秒），默认10秒。HTTP握手升级为ws协议超时时间
        configuration.setUpgradeTimeout(upgradeTimeout);
        // Ping消息超时时间（毫秒），默认60秒，这个时间间隔内没有接收到心跳消息就会发送超时事件
        configuration.setPingTimeout(pingTimeout);
        // Ping消息间隔（毫秒），默认25秒。客户端向服务器发送一条心跳消息间隔
        configuration.setPingInterval(pingInterval);
        configuration.setMaxFramePayloadLength(maxFramePayloadLength);
        configuration.setMaxHttpContentLength(maxHttpContentLength);
        //socket 鉴权
        configuration.setAuthorizationListener(new AuthorizationListener() {
            @Override
            public boolean isAuthorized(HandshakeData handshakeData) {
                //获取socket链接发来的token参数
                String clientId = handshakeData.getSingleUrlParam("clientId");
                String identification = handshakeData.getSingleUrlParam("identification");
                if (StringUtils.isEmpty(clientId) || StringUtils.isEmpty(identification)) {
                    return Boolean.FALSE;
                }

                log.info("--------------客户端连接成功:" + clientId );

                return Boolean.TRUE;
            }
        });

        SocketIOServer socketIOServer = new SocketIOServer(configuration);
//        //添加事件监听器
        socketIOServer.addListeners(socketIOHandler);
//        //启动SocketIOServer  没对接好 上传服务器暂时不开启socket
        socketIOServer.start();
        log.info("==========SocketIO启动完毕===========");
    }

}
